package com.qf.service.impl;

import com.qf.feign.CacheFeign;
import com.qf.model.StandardSubmit;
import com.qf.service.FilterChainService;
import com.qf.util.PushMsgUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 *
 * 五分钟限流策略
 * @author YDW
 * projectName:project2202_4
 * time:2022/6/20 22:30
 * description:
 */
@Service("limitFiveMinutes")
@Slf4j
public class LimitFiveMinutesFilterServiceImpl implements FilterChainService {
    @Autowired
    CacheFeign cacheFeign;
    @Autowired
    PushMsgUtil pushMsgUtil;
    @Override
    public boolean strategy(StandardSubmit submit) {
        log.info("[策略模块 -- 限流策略] 策略开始执行！ submit={}",submit);
        //获取客户端id
        Integer clientID = submit.getClientID();
        //获取发送手机号
        String destMobile = submit.getDestMobile();
        //获取发送内容
        String messageContent = submit.getMessageContent();
        //获取发送方式
        Integer source = submit.getSource();
        //先拼接临时key  例 client6to13364578+短信内容
        String key="client"+clientID+"to"+destMobile+messageContent;
        //flag1 ，2，3 分别表示 5分钟组，一小时组，24小时组是否可以存
        boolean flag1=false;
        boolean flag2=false;
        boolean flag3=false;
        // 判断5分钟组是否可存
        for (int i=1;i<=3;i++){//五分钟组只能存三条
            // 设置真实key 格式为 client+客户端id+to+手机号码+短信内容+5m+组内第几个（表示这是5分钟组）
            String rekey=key + ":5m" + i;
            String s = cacheFeign.get(rekey);
            //如果s为空，表示不存在此key，可存， 修改flag1=true，并存入，且跳出循环
            //只要获取的s中有一次为空，表示可存，flag1都会变为true，表示可存，且会把为空的那个key存入数据
            //如果三个都存满了，flag1仍为false，表示不可存
            if(StringUtils.isEmpty(s)){
                cacheFeign.set(key + ":5m" + i,messageContent,300L);
                flag1=true;
                break;
            }
        }
        // 判断一小时组是否可存
        for (int i=1;i<=5;i++){//一小时组只能有5个
            String rekey=key + ":1h" + i;
            String s = cacheFeign.get(rekey);
            if(StringUtils.isEmpty(s)){
                cacheFeign.set(key + ":1h" + i,messageContent,3600L);
                flag2=true;
                break;
            }
        }
        // 判断24小时组是否可存
        for (int i=1;i<=10;i++){
            String rekey=key + ":1d" + i;
            String s = cacheFeign.get(rekey);
            if(StringUtils.isEmpty(s)){
                cacheFeign.set(key + ":1d" + i,messageContent,3600*24L);
                flag3=true;
                break;
            }
        }

        //如果三个组都可存 ，表示没问题，直接通过即可
        if(flag1&&flag2&&flag3){
            log.info("[策略模块 -- 限流策略] 策略执行成功！ submit={}",submit);
            return true;
        }else {//只要有一个组不可存，就发送短信失败，return false，同时判断原因发送日志和报告
            if(!flag1){
                log.info("[策略模块 -- 限流策略] 5分钟内重复发送超三条，短信发送失败！ submit={}",submit);
                if(source==1){
                    pushMsgUtil.pushReport(submit,"5分钟内重复发送超三条!");
                }
                pushMsgUtil.sendLog(submit,"5分钟内重复发送超三条!");
                return false;

            }
            if(!flag2){
                log.info("[策略模块 -- 限流策略] 一小时内重复发送超5条，短信发送失败！ submit={}",submit);
                if(source==1){
                    pushMsgUtil.pushReport(submit,"一小时内重复发送超5条!");
                }
                pushMsgUtil.sendLog(submit,"一小时内重复发送超5条!");
                return false;

            }
            if(!flag3){
                log.info("[策略模块 -- 限流策略] 24小时内重复发送超10条，短信发送失败！ submit={}",submit);
                if(source==1){
                    pushMsgUtil.pushReport(submit,"24小时内重复发送超10条!");
                }
                pushMsgUtil.sendLog(submit,"24小时内重复发送超10条!");
                return false;

            }
            return false;

        }

    }
}
